package com.chebaohui.iqs.service.impl.deal.pingan.login;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.fastjson.JSONObject;
import com.chebaohui.iqs.sdk.chaojiying.ChaoJiYingSdk;
import com.chebaohui.iqs.service.impl.deal.pingan.util.HttpClientUtil;

/**
 * 平安登<新 2017年11月24日>
 * 
 * @author regase_xie
 *
 */
public class LoginNew {
	// private static void beforeTest() {//测试验证登录
	// Map<String, String> hearder = new HashMap<>();
	// hearder.put("Connection", "keep-alive");
	// hearder.put("Content-Type",
	// "application/x-www-form-urlencoded;charset=UTF-8");
	// hearder.put("Cookie",
	// "BIGipServerPOOL_PACLOUD_PRDR2017060601401=3540916652.56954.0000");
	// hearder.put("Host", "pacas-login.pingan.com.cn");
	// hearder.put("Origin", "https://pacas-login.pingan.com.cn");
	// hearder.put("Referer",
	// "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/login");
	// hearder.put("Accept", "application/json, text/javascript, */*; q=0.01");
	// hearder.put("Accept-Encoding", "gzip, deflate, br");
	// hearder.put("Accept-Language", "zh-CN,zh;q=0.9");
	// String four_url =
	// "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/auth.do";
	// Map<String, String> map = new HashMap<>();
	// map.put("username", username);
	// map.put("password",
	// "AAB93688E970A3339FC03829155600E726F8C2D1F47D01A9C6BFB61A01EF81458C7B2EADB30E9E5F8432B5172A27FA4FFA74E393855DA8EE81A427415EC99810989785140ED62C85EC263645E2AD6FFF3D7E9E70F6A5BA6B353A14E6D40DA709DCF9F288C58F735C53");
	// map.put("code", "SP47");
	// map.put("randCodeId",
	// "637400d7c1e812894dd914e0789f5159c871b4032-IC-9e90f8465e5298ac015e7041fa150006-14.106.228.58");
	// map.put("type", "");
	// map.put("appId", APPID);
	// map.put("clientCallBack", "");
	// try {
	// String res = PAHttpUtil.POST(hearder, four_url, map);
	// System.out.println(res);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }

	/**
	 * logger:日志工具.
	 */
	private static Log log = LogFactory.getLog(LoginNew.class);

	private final static String username = "CQHRBXDL-00002";// 平安登录用户名
	private final static String password = "AAB93688E970A3339FC03829155600E726F8C2D1F47D01A9C6BFB61A01EF81458C7B2EADB30E9E5F8432B5172A27FA4FFA74E393855DA8EE81A427415EC99810989785140ED62C85EC263645E2AD6FFF3D7E9E70F6A5BA6B353A14E6D40DA709DCF9F288C58F735C53";// "HUARUI123";//
																																																																// 平安登录密码
	private final static String APPID = "9e90f8465e5298ac015e7041fa150006";// 平安登录APPID

	private static boolean pingan_password_error = false;// 平安账户是否密码错误
	private static boolean FORCE_2_MODIFY_PWD = false;// 需要修改密码后才能登陆系统
	private static boolean WRONG_PASSWORD_OR_USERNAME = false;// 平安账户认证错误
	private static boolean pingan_risk = false;// 平安账户是否因为安全风险锁定
	private static boolean pingan_disabled = false;// 平安账户是否禁用
	private static final int CJY_MAX = 3;// 识码软件单次登陆识别最大次数

	/**
	 * 平安登陆
	 * 
	 * @return
	 */
	public static JSONObject login(CloseableHttpClient httpClient, HttpClientContext httpContext) throws Exception {
		if (pingan_password_error)
			throw new Exception("平安账户密码错误");
		if (FORCE_2_MODIFY_PWD)
			throw new Exception("平安账户需要修改密码后才能登陆系统");
		if (WRONG_PASSWORD_OR_USERNAME)
			throw new Exception("平安账户认证错误");
		if (pingan_risk)
			throw new Exception("平安账户因为安全风险锁定");
		if (pingan_disabled)
			throw new Exception("平安账户已禁用");

		try {
			// 第一步
			loginOne(httpClient, httpContext);

			// 第二步
			Map<String, String> two = null;

			// 第三步
			boolean three = false;

			// 第四步
			JSONObject four = null;

			for (int sb = 0; sb < CJY_MAX; sb++) {
				two = loginTwo(httpClient, httpContext);

				three = loginThree(httpClient, httpContext);
				if (!three)
					throw new Exception("登录第三步<不能获取验证码>错误");

				four = loginFour(httpClient, httpContext, two);

				if (four.getBooleanValue("state")) {// 登陆成功
					break;
				} else {// 验证码错误--<其它错误是异常>
					String error = ChaoJiYingSdk.errorResponse(two.get("picId"));
					log.info("验证码识别错误,调取其报错返分,结果:" + error);
				}
			}

			if (!four.getBooleanValue("state"))
				return four;
			// 转折关键处--------------
			// 第五步
			loginFive(httpClient, httpContext, four.getString("target"));

			// 第六步
			loginSix(httpClient, httpContext);

			return four;
		} catch (Exception e) {
			log.error("平安登录出现异常:" + e);
			throw new Exception("登录异常:" + e.getMessage());
		}
	}

	/**
	 * 登录--->第一步<访问首页>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @throws Exception
	 */
	private static void loginOne(CloseableHttpClient httpClient, HttpClientContext httpContext) throws Exception {
		try {
			// 访问首页地址
			String one_url = "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/login";

			HttpClientUtil._httpGetToBody(httpClient, httpContext, one_url);// 第一步进入首页
		} catch (Exception e) {
			throw new Exception("登录第一步<访问首页>异常:" + e.getMessage());
		}
	}

	/**
	 * 登录--->第二步<访问获取验证码>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @return
	 * @throws Exception
	 */
	private static Map<String, String> loginTwo(CloseableHttpClient httpClient, HttpClientContext httpContext)
			throws Exception {
		try {
			Map<String, String> result = new HashMap<>();
			String two_url = "https://pacas-login.pingan.com.cn/cas/genRandCode?param=" + new Date().getTime();
			ArrayList<BasicNameValuePair> two_param = new ArrayList<BasicNameValuePair>();
			two_param.add(new BasicNameValuePair("appId", APPID));
			JSONObject two_obj = JSONObject
					.parseObject(HttpClientUtil._httpPostToBody(httpClient, httpContext, two_url, two_param));// 第二步获取验证码

			String dataImg = two_obj.getString("dataImg");
			dataImg = dataImg.replaceAll("data:image/jpg;base64,", "");

			String imageKey = two_obj.getString("imageKey");

			Map<String, String> cjy = ChaoJiYingSdk.identifyBase64Img(dataImg);
			if ("true".equals(cjy.get("state"))) {
				result.put("state", "true");
			} else {
				result.put("state", "false");
				return result;
			}

			result.put("imageKey", imageKey);
			result.put("code", cjy.get("data"));// 验证码结果
			result.put("picId", cjy.get("pic_id"));// 验证码识别产品ID
			return result;
		} catch (Exception e) {
			throw new Exception("登录第二步<访问获取验证码>异常:" + e.getMessage());
		}
	}

	/**
	 * 登录--->第三步<访问确认是否获取验证码>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @return
	 * @throws Exception
	 */
	private static boolean loginThree(CloseableHttpClient httpClient, HttpClientContext httpContext) throws Exception {
		try {
			ArrayList<BasicNameValuePair> three_param = new ArrayList<BasicNameValuePair>();
			three_param.add(new BasicNameValuePair("appId", APPID));
			three_param.add(new BasicNameValuePair("userId", username));
			String three_url = "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/isNeedRandCode.do";
			JSONObject three_obj = JSONObject
					.parseObject(HttpClientUtil._httpPostToBody(httpClient, httpContext, three_url, three_param));// 第三步
			return "NEED_RAND_CODE".equals(three_obj.getString("isNeedRandCode"));
		} catch (Exception e) {
			throw new Exception("登录第三步<访问确认是否获取验证码>异常:" + e.getMessage());
		}
	}

	/**
	 * 登录--->第四步<提交登录请求>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @param question
	 * @return
	 * @throws Exception
	 */
	private static JSONObject loginFour(CloseableHttpClient httpClient, HttpClientContext httpContext,
			Map<String, String> question) throws Exception {
		String errorMessage = null;
		JSONObject four_obj = null;
		try {
			Map<String, String> hearder = new HashMap<>();
			hearder.put("Connection", "keep-alive");
			hearder.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
			hearder.put("Cookie", "BIGipServerPOOL_PACLOUD_PRDR2017060601401=3540916652.56954.0000");
			hearder.put("Host", "pacas-login.pingan.com.cn");
			hearder.put("Origin", "https://pacas-login.pingan.com.cn");
			hearder.put("Referer", "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/login");
			hearder.put("Accept", "application/json, text/javascript, */*; q=0.01");
			hearder.put("Accept-Encoding", "gzip, deflate, br");
			hearder.put("Accept-Language", "zh-CN,zh;q=0.9");
			// hearder.put("","");

			String four_url = "https://pacas-login.pingan.com.cn/cas/PA003/ICORE_PTS/auth.do";
			Map<String, String> map = new HashMap<>();
			map.put("username", username);
			map.put("password", password);

			map.put("code", question.get("code"));
			map.put("randCodeId", question.get("imageKey"));

			map.put("type", "");
			map.put("appId", APPID);
			map.put("clientCallBack", "");

			four_obj = JSONObject.parseObject(PAHttpUtil.POST(hearder, four_url, map));// 第四步<登录>

			errorMessage = four_obj.getString("errorMessage");

		} catch (Exception e) {
			throw new Exception("登录第四步<提交登录请求>异常:" + e.getMessage());
		}

		switch (errorMessage) {
		case "WRONG_IKEY_CODE":
			throw new Exception("登录第四步<提交登录请求>错误:" + "手机动态令牌验证码错误");
		case "WRONG_IMAGE_CODE":
			log.info("登录第四步<提交登录请求>错误:" + "验证码错误");
			four_obj.put("state", false);
			return four_obj;// throw new Exception("登录错误:" + "");
		case "USER_LOCKED":
			pingan_password_error = true;
			log.info("登录第四步<提交登录请求>错误:" + "密码错误");
			throw new Exception("登录第四步<提交登录请求>错误:" + "密码错误");
		case "USER_DISABLED":
			pingan_disabled = true;
			throw new Exception("登录第四步<提交登录请求>错误:" + "用户因90天未登录已被禁用");
		case "USER_RISK":
			pingan_risk = true;
			throw new Exception("登录第四步<提交登录请求>错误:" + "用户存在安全风险已被锁定");
		case "WRONG_PASSWORD_OR_USERNAME":
			WRONG_PASSWORD_OR_USERNAME = true;
			throw new Exception("登录第四步<提交登录请求>错误:" + "登录认证错误");
		case "FORCE_2_MODIFY_PWD":
			FORCE_2_MODIFY_PWD = true;
			throw new Exception("登录第四步<提交登录请求>错误:" + "需要修改密码后才能登陆系统");
		case "UNKNOW_EXCEPTION":
			throw new Exception("登录第四步<提交登录请求>错误:" + "未知错误,UNKNOW_EXCEPTION");
		case "LOGIN_SUCCESS":
			four_obj.put("state", true);
			log.info("登录第四步<提交登录请求>平安登陆成功...");
			return four_obj;
		default:
			throw new Exception("登录第四步<提交登录请求>错误:" + "未知错误,default");
		}
	}

	/**
	 * 登录--->第五步<跳转到登录后首页>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @param five_url
	 * @throws Exception
	 */
	private static void loginFive(CloseableHttpClient httpClient, HttpClientContext httpContext, String five_url)
			throws Exception {
		try {
			HttpClientUtil._httpGetToBody(httpClient, httpContext, five_url);// 第五步进入首页

			HttpClientUtil._httpGetToBody(httpClient, httpContext,
					"https://icore-pts.pingan.com.cn/ebusiness/login.do");

			HttpClientUtil._httpGetToBody(httpClient, httpContext,
					"https://icore-pts.pingan.com.cn/ebusiness/frames/main_02.jsp");

		} catch (Exception e) {
			throw new Exception("登录第五步<跳转到登录后首页>异常:" + e.getMessage());
		}
	}

	/**
	 * 登录--->第六步<跳转到算费页>
	 * 
	 * @param httpClient
	 * @param httpContext
	 * @throws Exception
	 */
	private static void loginSix(CloseableHttpClient httpClient, HttpClientContext httpContext) throws Exception {
		try {
			HttpGet httpGet = new HttpGet(
					"https://icore-pts.pingan.com.cn/ebusiness/auto/newness/toibcswriter.do?transmitId=apply");
			CloseableHttpResponse response3 = httpClient.execute(httpGet, httpContext);
			String three = EntityUtils.toString(response3.getEntity());
			String cookie = "";
			List<Cookie> lc = httpContext.getCookieStore().getCookies();
			for (int i = 0; i < lc.size(); i++) {
				if (lc.get(i).getName().equals("BIGipServericore-pts_http_DMZ_PrdPool"))
					cookie = cookie + "BIGipServerICORE-PNBS_DMZ_PrdPool=" + lc.get(i).getValue() + ";";
				else if (lc.get(i).getName().equals("WLS_HTTP_BRIDGE_ICOREPTS"))
					cookie = cookie + "JSESSIONID=" + lc.get(i).getValue() + ";";
				else if (lc.get(i).getName().equals("_WL_AUTHCOOKIE_WLS_HTTP_BRIDGE_ICOREPTS"))
					cookie = cookie + "_WL_AUTHCOOKIE_JSESSIONID=tfwVcyMd-wJavwFk-EL-=" + lc.get(i).getValue();
			}

			String sixUrl = Jsoup.parse(three).getElementById("workbenchIBCSAppForm").attr("action");

			HttpPost httpPost = new HttpPost(sixUrl);
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(getFourParam(three), Consts.UTF_8);
			httpPost.setEntity(entity);
			httpPost.setHeader("Cookie", cookie);
			httpPost.setHeader("Origin", " https://icore-pts.pingan.com.cn");
			httpPost.setHeader("Accept-Encoding", "gzip, deflate, br");
			httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.8");
			httpPost.setHeader("Upgrade-Insecure-Requests", "1");
			httpPost.setHeader("User-Agent",
					"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36");
			httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
			httpPost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
			httpPost.setHeader("Cache-Control", "max-age=0");
			httpPost.setHeader("Referer",
					"https://icore-pts.pingan.com.cn/ebusiness/auto/newness/toibcswriter.do?transmitId=apply");
			httpPost.setHeader("Connection", "keep-alive");
			CloseableHttpResponse response = httpClient.execute(httpPost, httpContext);

			try {
				String html = EntityUtils.toString(response.getEntity());
				html = html.substring(html.indexOf("outSystemDateMap"));
				html = html.substring(html.indexOf("{"));
				html = html.substring(0, html.indexOf(";"));
				JSONObject json = JSONObject.parseObject(html);

				JSONObject postParams = json.getJSONObject("postParams");
				String urls = "https://icorepnbs.pingan.com.cn/icore_pnbs/do/app/cache/switch/preQuoteValidate?departmentCode="
						+ postParams.getString("departmentCode") + "&businessSourceCode="
						+ postParams.getString("businessSourceCode") + "&businessSourceDetailCode="
						+ postParams.getString("businessSourceDetailCode") + "&channelSourceCode="
						+ postParams.getString("channelSourceCode") + "&channelSourceDetailCode="
						+ postParams.getString("channelSourceDetailCode");

				HttpClientUtil._httpGetToBody(httpClient, httpContext, urls);
			} finally {
				response.close();
			}
		} catch (Exception e) {
			throw new Exception("登录第六步<跳转到算费页>异常:" + e.getMessage());
		}
	}

	/**
	 * 获取请求参数
	 * 
	 * @param six_one
	 *            第六步返回html
	 * @return
	 */
	private static ArrayList<BasicNameValuePair> getFourParam(String six_one) {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		Elements inputs = Jsoup.parse(six_one).getElementById("workbenchIBCSAppForm").select("input");
		for (Element input : inputs) {
			if ("text".equals(input.attr("type"))) {
				params.add(new BasicNameValuePair(input.attr("name"), input.attr("value")));
			}
		}
		return params;
	}
}
